#pragma once
#include <vector>
#include "mysql.hpp"
#include "logger.hpp"
#include "user.hxx" 
#include "user-odb.hxx"
namespace zzy_mims
{
    class UserTable
    {
    public:
        using ptr = std::shared_ptr<UserTable>;
        UserTable(const std::shared_ptr<odb::core::database>& db):_db(db){};
        bool insert(const std::shared_ptr<User>& user)
        {
            try
            {
                odb::transaction trans(_db->begin());
                _db->persist(*user);
                trans.commit();
            }catch(std::exception& e)
            {
                LOG_ERROR("新增用户失败{}:{}",user->nickname(),e.what());
                return false;
            }
            return true;
        }
        bool update(const std::shared_ptr<User>& user)
        {
            try
            {
                odb::transaction trans(_db->begin());
                _db->update(*user);
                trans.commit();
            }catch(std::exception& e)
            {
                LOG_ERROR("更新用户失败{}:{}",user->nickname(),e.what());
                return false;
            }
            return true;
        }
        std::shared_ptr<User> select_by_id(const std::string& user_id)
        {
            std::shared_ptr<User> ret;
            try
            {
                odb::transaction trans(_db->begin());
                ret.reset(_db->query_one<User>(odb::query<User>::user_id==user_id));
                trans.commit();
            }catch(std::exception& e)
            {
                LOG_ERROR("通过id查询用户失败{}",e.what());
            }
            return ret;
        }
        std::shared_ptr<User> select_by_nickname(const std::string& nickname)
        {
            std::shared_ptr<User> ret;
            try
            {
                odb::transaction trans(_db->begin());
                ret.reset(_db->query_one<User>(odb::query<User>::nickname==nickname));
                trans.commit();
            }catch(std::exception& e)
            {
                LOG_ERROR("通过用户名查询用户失败{}",e.what());
            }
            return ret;
        }
        std::shared_ptr<User> select_by_phone(const std::string& phone)
        {
            std::shared_ptr<User> ret;
            try
            {
                odb::transaction trans(_db->begin());
                ret.reset(_db->query_one<User>(odb::query<User>::phone==phone));
                trans.commit();
            }catch(std::exception& e)
            {
                LOG_ERROR("通过手机号查询用户失败{}",e.what());
            }
            return ret;
        }
        std::vector<zzy_mims::User> select_multi_users(const std::vector<std::string>& id_list)
        {
            //select * from user where user_id in ('id1','id2'...)
            std::vector<zzy_mims::User> ret;
            if(!id_list.size())
            return ret;
            try
            {
                odb::transaction trans(_db->begin());
                std::string condition = "user_id in ('"+id_list[0]+"'";
                for(int i =1;i<id_list.size();i++)
                condition+=(std::string)","+"'"+id_list[i]+"'";
                condition+=")";
                odb::result<User> res(_db->query<User>(condition));
                for(auto &e:res)
                ret.emplace_back(e);
                trans.commit();
            }catch(std::exception& e)
            {
                LOG_ERROR("通过用户id批量查询用户失败{}",e.what());
            }
            return ret;
        }
    private:
    std::shared_ptr<odb::core::database> _db;
    };
}
